﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKRGeometry;

namespace LightSmokeTemperatureCameraAdjust
{
	internal class AdhesionCalculation
	{
		private bool JudgeMoveOrNot(FamilyInstance familyInstance)
		{
			return familyInstance.Host == null;
		}

		public List<KeyValuePair<Element, double>> FindNearCeilingOrFloor(List<Element> inputlstElements, CeilingOrFloorSearcher useSearcher, bool bIsCeilOrFloor)
		{
			foreach (Element element in inputlstElements)
			{
				if (this.JudgeMoveOrNot(element as FamilyInstance))
				{
					if (bIsCeilOrFloor)
					{
						this.PointProjectFace(element, true, useSearcher);
					}
					else
					{
						this.PointProjectFace(element, false, useSearcher);
					}
				}
			}
			return this.m_LstInfoReadyMove;
		}

		private bool PointProjectFace(Element element, bool bIsCeilOrFloor, CeilingOrFloorSearcher useSearcher)
		{
			XYZ point = (element.Location as LocationPoint).Point;
			double z = point.Z;
			bool flag = false;
			List<CelingOrFloorStructure> list;
			if (bIsCeilOrFloor)
			{
				list = useSearcher.GetCelingList();
			}
			else
			{
				list = useSearcher.GetFloorList();
			}
			foreach (CelingOrFloorStructure celingOrFloorStructure in list)
			{
				if (bIsCeilOrFloor && Geometry.Lessthan_Or_Equal(z, celingOrFloorStructure.m_dLevel))
				{
					flag = this.JudgePointProjectFace(element, celingOrFloorStructure, point);
					if (flag)
					{
						break;
					}
				}
				else if (!bIsCeilOrFloor && Geometry.Lessthan_Or_Equal(z, celingOrFloorStructure.m_dLevel))
				{
					flag = this.JudgePointProjectFace(element, celingOrFloorStructure, point);
					if (flag)
					{
						break;
					}
				}
			}
			return flag;
		}

		public bool JudgePointProjectFace(Element element, CelingOrFloorStructure structure, XYZ locationPoint)
		{
			foreach (CelingOrFloorFaceInfo celingOrFloorFaceInfo in structure.m_lstFaceInfo)
			{
				foreach (Face face in celingOrFloorFaceInfo.m_listFace)
				{
					IntersectionResult intersectionResult = face.Project(locationPoint);
					if (intersectionResult != null)
					{
						XYZ xyzpoint = intersectionResult.XYZPoint;
						XYZ xyz = (xyzpoint - locationPoint).Normalize();
						double num = locationPoint.DistanceTo(xyzpoint);
						double num2 = XYZ.BasisZ.AngleTo(xyz);
						if (num2 < Math.PI*.5)
						{
							num /= Math.Cos(num2);
							this.m_LstInfoReadyMove.Add(new KeyValuePair<Element, double>(element, num));
							return true;
						}
					}
				}
			}
			return false;
		}

		public List<KeyValuePair<Element, double>> m_LstInfoReadyMove = new List<KeyValuePair<Element, double>>();
	}
}
